import { matchRoutes } from 'react-router-dom';
import { IMenuItem, IRouteItem } from './RouteType';

/**
 * 使用glob完成自动化导入，自动生成约定式路由routes
 * Index.tsx 路由入口文件
 * page.ts 路由属性配置
 */

/** 获取所有路由默认文件 */
const pageModules = import.meta.glob('../pages/**/page.ts', {
  eager: true,
  import: 'default',
});

/** 获取所有路由对应的配置文件 */
const compModules = import.meta.glob('../pages/**/Index.tsx', {
  eager: true,
  import: 'default',
});

export const routes: IRouteItem[] = Object.entries(pageModules).map(
  ([pagePath, config]): IRouteItem => {
    let path = pagePath.replace('../pages', '').replace('/page.ts', '');

    // 根据路由路径获取其父级路径，方便生成树型菜单等
    let parentPath = path.slice(0, path.lastIndexOf('/'));

    path = path || '/';
    if (path === '/') {
      parentPath = '';
    } else {
      parentPath = parentPath ? parentPath : '/';
    }

    const name = path.split('/').filter(Boolean).join('-') || 'index';
    const compPath = pagePath.replace('page.ts', 'Index.tsx');

    return {
      name,
      path,
      key: path,
      component: compModules[compPath],
      parentPath,
      ...(config as any),
    };
  },
);

/**
 * 将树形结构数据转为平级数组 （树形菜单和扁平数组）
 * @param tree
 * @returns
 */
export function treeConvertToArr(tree: IRouteItem[]) {
  let arrs: IRouteItem[] = [];
  let result = [];
  arrs = arrs.concat(tree);

  while (arrs.length) {
    let first = arrs.shift(); // 弹出第一个元素
    if (first?.children) {
      //如果有children
      arrs = arrs.concat(first.children);
      delete first['children'];
    }
    result.push(first);
  }
  return result;
}

/**
 * 递归格式化菜单成标准树
 */
export const generateTree = (
  tree: IRouteItem[] = [],
  result: IRouteItem[] = [],
) => {
  tree.forEach((item: IRouteItem) => {
    // item.path = ['/data', item.path === '/' ? '' : item.path].join('');

    let menu: any = {
      ...item,
      key: item.path,
    };

    if (item.children) {
      generateTree(item.children, menu.children);
    } else {
      // Antd框架Menu组件中，children为空数组时无法点击
      menu.children = undefined;
    }

    result.push(menu);
  });

  return result;
};

/**
 * 获取有效菜单：不设置隐藏的+不是叶子节点的
 * @param tree
 * @returns
 */
export const getValidMenus = (
  tree: IRouteItem[] = [],
  result: IMenuItem[] = [],
  ignoreHide?: boolean,
) => {
  const treeData = ignoreHide ? tree : tree.filter((v) => !v.hideInMenu);
  treeData.map((item, idx) => {
    const { path, label, type, target } = item;
    const node: IMenuItem = {
      key: path ?? '',
      label,
      type,
      target,
    };

    const hasChild = item?.children?.find((v) => !v.hideInMenu);

    if (item?.children) {
      if (hasChild) {
        node.children = getValidMenus(item.children, result?.[idx]?.children);
      } else {
        node.children = undefined;
      }
    }

    result.push(node);
  });

  return result;
};

/**
 * 根据路由key查询匹配父级路由
 * @param tree
 * @param pathname
 */
export const getParentsByPath = (tree: IRouteItem[], pathname: string) => {
  const routeList = matchRoutes(tree as any, pathname);

  let pathList: string[] = [];

  if (routeList !== null) {
    for (let i = 0; i < routeList.length; i++) {
      const routeItem = routeList[i];
      let path = routeItem.route.path;
      if (path) {
        pathList.push(path);
      }
    }
  }

  return { routeList, pathList } as any;
};

/**
 * 查找菜单索引
 * @param tree
 * @param item
 * @returns
 */
export const findItemIndex = (tree: IRouteItem[] = [], item?: IRouteItem) => {
  if (!item) {
    return -1;
  }
  var objStr = JSON.stringify(item);
  return tree.reduce((index, ele, i) => {
    if (JSON.stringify(ele) === objStr) {
      return i;
    } else {
      return index;
    }
  }, -1);
};

/**
 * 根据当前路由反查菜单信息
 * @param pathname
 * @returns
 */
export const getMenuInfoByPath = (tree: IRouteItem[], pathname: string) => {
  const { routeList, pathList } = getParentsByPath(tree, pathname);

  const parentKeys: string[] = pathList;
  const parents: IRouteItem[] = routeList?.map(
    (item: any) => item.route,
  ) as IRouteItem[];

  const topMenu: IRouteItem = parents?.[0] ?? null;
  const topMenuChildren: IRouteItem[] = (topMenu?.children ?? [])?.filter(
    (v) => v.path !== topMenu?.path,
  );

  const currentMenu: IRouteItem = parents?.[parents?.length - 1] ?? null;
  const currentChildren = currentMenu?.children ?? [];
  const currentMenuIndex = findItemIndex(parents, currentMenu);

  const parentMenu: IRouteItem = parents?.[currentMenuIndex - 1] ?? null;
  const parentMenuChildren = parentMenu?.children ?? [];

  return {
    parents,
    parentKeys,

    topMenu,
    topMenuChildren,

    currentMenu,
    currentChildren,
    currentMenuIndex,

    parentMenu,
    parentMenuChildren,
  };
};
